/*******************************************************************************
 *
 * Set of internal macros - it should not be included by external users of
 * this framework
 *
 ******************************************************************************/
#ifndef TRACE_MACROS_H
#define TRACE_MACROS_H

#include "Trace.h"

namespace tsc
{
namespace common
{

#define TIMESTAMP_FORMAT "[%4u%02u%02u_%02u%02u%02u:%06u]"
#define TIMESTAMP_VALUES(tm,timeval) tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (unsigned int)(timeval.tv_usec)

#define INST tsc::common::TraceManager::instance()

#define STRINGIFY(x) #x

/*******************************************************************************
 *
 * Macro for internal use only
 *
 ******************************************************************************/
#define TRACE_CHECK_AND_CALL(TRACE, FORMAT, ARGS...)\
do{\
  if (INST->isTraceEnabled(TRACE ## _GROUP))\
  {\
	  INST->lock();\
	  INST->printTraceHeader(__FILE__, __LINE__, INST->processName(), TRACE ## _GROUP) \
	  << INST->doStr(FORMAT, ##ARGS) << std::endl;\
	  INST->unlock();\
  }\
}while(0)

/*******************************************************************************
 *
 * Macro for internal use only
 *
 ******************************************************************************/
#define TRACE_OBJ_CHECK_AND_STREAM(TRACE_OBJ, TRACE, MSG)\
do{\
  if (INST->isTraceObjEnabled(STRINGIFY(TRACE_OBJ), TRACE ## _GROUP))\
  {\
	  INST->lock();\
	  INST->printTraceHeader(__FILE__, __LINE__, STRINGIFY(TRACE_OBJ), TRACE ## _GROUP)\
	  	  << MSG << std::endl;\
	  INST->unlock();\
  }\
}while(0)


/*******************************************************************************
 *
 * Macro for internal use only
 *
 ******************************************************************************/
#define TRACE_OBJ_CHECK_AND_CALL(TRACE_OBJ, TRACE, FORMAT, ARGS...)\
do{\
  if (INST->isTraceObjEnabled(STRINGIFY(TRACE_OBJ), TRACE ## _GROUP))\
  {\
	  INST->lock();\
	  INST->printTraceHeader(__FILE__, __LINE__, STRINGIFY(TRACE_OBJ), TRACE ## _GROUP) \
	  << INST->doStr(FORMAT, ##ARGS) << std::endl;\
	  INST->unlock();\
  }\
}while(0)

/*******************************************************************************
 *
 * Macro for internal use only
 *
 ******************************************************************************/
#define TRACE_CHECK_AND_BUS(TRACE, DATA, SIZE, FORMAT, ARGS...)\
do{\
  if (INST->isTraceEnabled(TRACE ## _GROUP))\
  {\
	  INST->lock();\
	  INST->printTraceHeader(__FILE__, __LINE__, INST->processName(), TRACE ## _GROUP) \
	    << INST->doStr(FORMAT, ##ARGS) << std::endl \
	    << "Size: " << SIZE << ", data: " << std::endl \
	    << INST->hexDump(DATA, SIZE) << std::endl;\
	  INST->unlock();\
  }\
}while(0)

} // namespace common
} // namespace tsc

#endif // TRACE_MACROS_H
